package cz.muni.fi.pa165.musiclibrary.musiclibraryweb.pages.search.result;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
import org.apache.wicket.extensions.markup.html.tabs.ITab;
import org.apache.wicket.extensions.markup.html.tabs.TabbedPanel;
import org.apache.wicket.markup.head.CssHeaderItem;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.model.StringResourceModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.request.resource.CssResourceReference;
import org.apache.wicket.spring.injection.annot.SpringBean;

import cz.muni.fi.pa165.musiclibrary.api.service.IAlbumService;
import cz.muni.fi.pa165.musiclibrary.api.service.IArtistService;
import cz.muni.fi.pa165.musiclibrary.api.service.ISongService;
import cz.muni.fi.pa165.musiclibrary.api.service.dto.IAlbumDTO;
import cz.muni.fi.pa165.musiclibrary.api.service.dto.IArtistDTO;
import cz.muni.fi.pa165.musiclibrary.api.service.dto.ISongDTO;
import cz.muni.fi.pa165.musiclibrary.musiclibraryweb.pages.AbstractMusicLibraryPage;

/**
 *
 * @author Maros Kucbel
 * @date 2012-11-21T19:57:57+0100
 */
public final class SearchResultPage extends AbstractMusicLibraryPage {

    @SpringBean
    private ISongService songService;
    @SpringBean
    private IArtistService artistService;
    @SpringBean
    private IAlbumService albumService;
    
    /**
     * Constructor.
     */
    public SearchResultPage() {
        this(new PageParameters());
    }
    
    /**
     * Constructor
     * @param pageParameters Parameters for page initialization.
     */
    public SearchResultPage(final PageParameters pageParameters) {
        super(pageParameters);
    }

    @Override
    public void renderHead(IHeaderResponse response) {
        
        response.render(CssHeaderItem.forReference(new CssResourceReference(SearchResultPage.class, "SearchResultPage.css")));
        super.renderHead(response);
    }

    @Override
    protected void onInitialize() {
        super.onInitialize();
        this.initComponents();
    }
    
    private void initComponents() {
        PageParameters pageParameters = this.getPageParameters();
        final String searchString = pageParameters.get("s").toOptionalString();
        
        List<ITab> tabs = new ArrayList<ITab>(3);
        tabs.add(new AbstractTab(new StringResourceModel("SearchResultPage.tabbedPanel.tab.songs", this, null)) {

            @Override
            public WebMarkupContainer getPanel(String panelId) {
                List<ISongDTO> songs = SearchResultPage.this.getSongs(searchString);
                return new SongsPanel(panelId, songs);
            }
        });
        tabs.add(new AbstractTab(new StringResourceModel("SearchResultPage.tabbedPanel.tab.artists", this, null)) {

            @Override
            public WebMarkupContainer getPanel(String panelId) {
                List<IArtistDTO> aritsts = SearchResultPage.this.getArtists(searchString);
                return new ArtistsPanel(panelId, aritsts);
            }
        });
        tabs.add(new AbstractTab(new StringResourceModel("SearchResultPage.tabbedPanel.tab.albums", this, null)) {

            @Override
            public WebMarkupContainer getPanel(String panelId) {
                Map<IAlbumDTO, List<IArtistDTO>> albums = SearchResultPage.this.getAlbums(searchString);
                return new AlbumsPanel(panelId, albums);
            }
        });
        
        TabbedPanel<ITab> tabbedPanel = new TabbedPanel<ITab>(ComponentIDs.TABBED_PANEL, tabs);
        this.add(tabbedPanel);
    }
    
    /**
     * Returns list of songs, whose name contains search string.
     */
    private List<ISongDTO> getSongs(String searchString) {
        List<ISongDTO> songs = new ArrayList<ISongDTO>();
        if (StringUtils.isNotBlank(searchString) && searchString.length() > 2) {
            songs.addAll(this.songService.getByTitle(searchString));
        }
        return songs;
    }
    
    private List<IArtistDTO> getArtists(String searchString) {
        List<IArtistDTO> artists = new ArrayList<IArtistDTO>();
        if (StringUtils.isNotBlank(searchString) && searchString.length() > 2) {
            artists.addAll(this.artistService.getByName(searchString));
        }
        return artists;
    }
    
    private Map<IAlbumDTO, List<IArtistDTO>> getAlbums(String searchString) {
        Map<IAlbumDTO, List<IArtistDTO>> albumMap = 
                new HashMap<IAlbumDTO, List<IArtistDTO>>();
        List<IAlbumDTO> albums = new ArrayList<IAlbumDTO>();
        if (StringUtils.isNotBlank(searchString) && searchString.length() > 2) {
            albums.addAll(this.albumService.getByTitle(searchString));
        }
        for (final IAlbumDTO album : albums) {
            Set<IArtistDTO> artists = new HashSet<IArtistDTO>();
            for (final ISongDTO song : this.songService.getByAlbum(album)) {
                artists.add(song.getArtist());
            }
            albumMap.put(album, new ArrayList<IArtistDTO>(artists));
        }
        return albumMap;
    }
    
    /** Identifiers of added components. */
    private static final class ComponentIDs {
        /** Panel with tabs. */
        private static final String TABBED_PANEL = "tabbedPanel";
    }
}